﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FXnaGis;

using System.ComponentModel;

using System.Threading.Tasks;

using FXnaInfrastructure;


using DotSpatial.Topology;




namespace NSCore
{
    /// <summary>
    /// 提供所有的数学计算服务,
    /// 我们在这里尝试写一个
    /// 计算过程一定要和数据保存分开
    /// </summary>
    public class NSMath
    {

        public NSMath(BackgroundWorker worker)
        {
            this._worker = worker;

          

 
        }



       





        int _totalReceptor;

        /// <summary>
        /// 当前计算的总接收点数量
        /// </summary>
        public int TotalReceptor
        {
            get { return _totalReceptor; }
            set { _totalReceptor = value; }
        }


        BackgroundWorker _worker;




        MathCore _mathCore;

        /// <summary>
        /// 计算核心
        /// </summary>
        public MathCore MathCore
        {
            get { return _mathCore; }
            set { _mathCore = value; }
        }



        /// <summary>
        /// 计算所有时段
        /// </summary>
        /// <param name="data"></param>
        /// <param name="nr"></param>
        public void Compute(NSData data,NSResult nr)
        {


            //我们需要为计算提供各种各样的参数


            this._mathCore = new MathCore(data);



            //首先重置结果数据位原始状态


            nr.ResetMainGridResult(data);





            //最外围是根据时间段，来划分

            //我们首先来计算白天的值

            //构建合理的计算输入端

            foreach (TimeDivision item in data.TimeDivides.Entities)
            {

                this.Compute(data,nr,item);

                
            }





          

            
           



         


            

    
        }



        /// <summary>
        /// 指定计算单一时段
        /// </summary>
        /// <param name="data"></param>
        /// <param name="nr"></param>
        /// <param name="division"></param>
        public void Compute(NSData data, NSResult nr, TimeDivision division)
        {

            //在这里我们要读取对应的运行参数





            //初始化参数

            NSContext context = new NSContext(data,division);

         
            




            //需要根据接收点的数量，和当前的位置来核算目前计算的进程，以回报给用户


            //我们这里以离散点为基础，进行测试

            this._totalReceptor = data.ScatterLayer.Shapes.Count;




            this.ComputeGrid(data, nr,context);





 

        }



        public void ComputeGrid(NSData data,NSResult  nr,NSContext context)
        {


            






            List<MathReceptor> receptors = new List<MathReceptor>();




            //循环网格接受点 ,准备开始网格的计算

            foreach (FShape shp in data.GridLayer.Shapes.Values)
            {
                GridReceptor gr = shp as GridReceptor;

                FGrid grid = gr.InnerShape.Grid;

                for (int i = 0; i < grid.NX; i++)
                {
                    for (int j = 0; j < grid.NY; j++)
                    {


                        //如果我再这里，虚拟点接受，会是什么情况呢





                        //后面的参数是默认离地高度

                        Coordinate c = new Coordinate(grid.GetXPos(i), grid.GetXPos(j), gr.Height);

                        MathReceptor mr = new MathReceptor(c);

                        //将参数传递部分和实际运算部分分开

                        receptors.Add(mr);





                    }

                }



                //执行计算，并返回



              

                //具体执行计算的代码

                this._mathCore.Compute(receptors, context);



                //计算完成后，保存数据


                TimedGridResult tgr = nr.MainGrids.GetEntity(gr.Id) as TimedGridResult;


                //这里我们取得第一个做测试，然后在更改

              // GridResult mgr = tgr.Childrens.Values.ToList<GridResult>()[0];


                GridResult mgr = tgr.Childrens[context.CurrentDivision];


                int index = 0;


                for (int i = 0; i < grid.NX; i++)
                {
                    for (int j = 0; j < grid.NY; j++)
                    {

                        //后面的参数是默认离地高度

                        
                        //这里我们只测试线测试一下白天的，之后一定会更改


                       // tgr.Childrens[].ContribueValue[i, j] = receptors[index].ContributeValue;

                        //这里需要注意，当没有声源时，返回的是null




                        mgr.ContribueValue[i, j] = (double)receptors[index].ContributeValue;



                        index++;


                    }

                }




                //循环之后，向结果中添加数据


              




            }



          


          



 
        }



      

    }
}
